package com.warom.sdg.webview.jsinterface;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.webkit.JavascriptInterface;

import com.google.gson.Gson;
import com.warom.sdg.config.MeasurementPoint;
import com.warom.sdg.config.PlcMeasurementConfig;
import com.warom.sdg.enums.ModuleType;
import com.warom.sdg.model.ApiResponse;
import com.warom.sdg.webview.BaseWebViewJsInterface;
import com.warom.sdg.webview.WebViewWrapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

/**
 * 粮情检测专用WebViewJsInterface
 * 提供粮情检测页面所需的JavaScript接口，用于获取温湿度等粮情数据
 */
public class WebViewJsGrainSituationInterface extends BaseWebViewJsInterface {
    private static final String TAG = "GrainSituationJsInterface";
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private final Gson gson = new Gson();
    private final ExecutorService executor = Executors.newSingleThreadExecutor();

    private WebViewWrapper webViewWrapper;

    /**
     * 构造函数
     * @param context 上下文
     */
    public WebViewJsGrainSituationInterface(Context context) {
        super(context, null);
    }

    /**
     * 构造函数
     * @param context 上下文
     * @param webViewWrapper WebView包装器
     */
    public WebViewJsGrainSituationInterface(Context context, WebViewWrapper webViewWrapper) {
        super(context, webViewWrapper);
        this.webViewWrapper = webViewWrapper;
    }

    /**
     * 异步获取粮情数据
     * @param args 参数
     * @param requestId 请求ID
     */
    @JavascriptInterface
    public void getGrainSituationDataAsync(String args, String requestId) {
        executor.execute(() -> getGrainSituationData(args, result -> handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 异步获取温度数据
     * @param args 参数
     * @param requestId 请求ID
     */
    @JavascriptInterface
    public void getTemperatureDataAsync(String args, String requestId) {
        executor.execute(() -> getTemperatureData(args, result -> handleAsyncResponse(requestId, result)));
    }
    
    /**
     * 异步获取湿度数据
     * @param args 参数
     * @param requestId 请求ID
     */
    @JavascriptInterface
    public void getHumidityDataAsync(String args, String requestId) {
        executor.execute(() -> getHumidityData(args, result -> handleAsyncResponse(requestId, result)));
    }

    /**
     * 异步获取历史数据的平均值
     * @param args JSON字符串，包含 { cableNos: [1, 2, ...], durationMinutes: 1440 }
     * @param requestId 请求ID
     */
    @JavascriptInterface
    public void getHistoryGrainSituationDataAsync(String args, String requestId) {
        executor.execute(() -> {
            try {
                HistoricalDataRequest request = gson.fromJson(args, HistoricalDataRequest.class);
                if (request == null || request.cableNos == null || request.cableNos.isEmpty()) {
                    handleAsyncResponse(requestId, ApiResponse.success(new ArrayList<>()).toJson());
                    return;
                }
                getHistoricalAverageData(request.cableNos, request.durationMinutes, result -> handleAsyncResponse(requestId, result));
            } catch (Exception e) {
                Log.e(TAG, "获取历史平均数据失败", e);
                ApiResponse<Object> response = ApiResponse.error("获取历史平均数据失败: " + e.getMessage());
                handleAsyncResponse(requestId, response.toJson());
            }
        });
    }

    // 实际业务处理 - 获取所有粮情数据(温度+湿度)
    private void getGrainSituationData(String argsJson, Consumer<String> callback) {
        try {
            // 获取粮情检测模块对应的设备-测点映射
            Map<com.warom.sdg.model.DeviceType, List<MeasurementPoint>> grainSituationMap =
                PlcMeasurementConfig.moduleDevicePointsMap.get(ModuleType.GRAIN_SITUATION);
            
            // 如果映射为空，返回空列表
            if (grainSituationMap == null || grainSituationMap.isEmpty()) {
                ApiResponse<List<MeasurementPoint>> response =
                    ApiResponse.success("获取粮情数据成功", new ArrayList<>());
                callback.accept(response.toJson());
                return;
            }
            
            // 收集所有设备的测点到一个列表
            List<MeasurementPoint> allPoints = new ArrayList<>();
            for (List<MeasurementPoint> devicePoints : grainSituationMap.values()) {
                if (devicePoints != null && !devicePoints.isEmpty()) {
                    allPoints.addAll(devicePoints);
                }
            }
            
            // 返回所有测点的JSON，使用ApiResponse格式
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.success("获取粮情数据成功", allPoints);
            callback.accept(response.toJson());
        } catch (Exception e) {
            Log.e(TAG, "获取粮情检测数据失败", e);
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.error("获取粮情检测数据失败: " + e.getMessage());
            callback.accept(response.toJson());
        }
    }
    
    // 实际业务处理 - 只获取温度数据
    private void getTemperatureData(String argsJson, Consumer<String> callback) {
        try {
            // 获取粮情检测模块对应的设备-测点映射
            Map<com.warom.sdg.model.DeviceType, List<MeasurementPoint>> grainSituationMap =
                PlcMeasurementConfig.moduleDevicePointsMap.get(ModuleType.GRAIN_SITUATION);
            
            // 如果映射为空，返回空列表
            if (grainSituationMap == null || grainSituationMap.isEmpty()) {
                ApiResponse<List<MeasurementPoint>> response =
                    ApiResponse.success("获取温度数据成功", new ArrayList<>());
                callback.accept(response.toJson());
                return;
            }
            
            // 收集所有设备的温度测点到一个列表
            List<MeasurementPoint> temperaturePoints = new ArrayList<>();
            for (List<MeasurementPoint> devicePoints : grainSituationMap.values()) {
                if (devicePoints != null && !devicePoints.isEmpty()) {
                    // 筛选温度传感器测点
                    for (MeasurementPoint point : devicePoints) {
                        if (point.getDeviceSubType() == MeasurementPoint.DeviceSubType.TEMPERATURE_SENSOR) {
                            temperaturePoints.add(point);
                        }
                    }
                }
            }
            
            // 返回温度测点的JSON，使用ApiResponse格式
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.success("获取温度数据成功", temperaturePoints);
            callback.accept(response.toJson());
        } catch (Exception e) {
            Log.e(TAG, "获取粮情温度数据失败", e);
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.error("获取温度数据失败: " + e.getMessage());
            callback.accept(response.toJson());
        }
    }
    
    // 实际业务处理 - 只获取湿度数据
    private void getHumidityData(String argsJson, Consumer<String> callback) {
        try {
            // 获取粮情检测模块对应的设备-测点映射
            Map<com.warom.sdg.model.DeviceType, List<MeasurementPoint>> grainSituationMap =
                PlcMeasurementConfig.moduleDevicePointsMap.get(ModuleType.GRAIN_SITUATION);
            
            // 如果映射为空，返回空列表
            if (grainSituationMap == null || grainSituationMap.isEmpty()) {
                ApiResponse<List<MeasurementPoint>> response =
                    ApiResponse.success("获取湿度数据成功", new ArrayList<>());
                callback.accept(response.toJson());
                return;
            }
            
            // 收集所有设备的湿度测点到一个列表
            List<MeasurementPoint> humidityPoints = new ArrayList<>();
            for (List<MeasurementPoint> devicePoints : grainSituationMap.values()) {
                if (devicePoints != null && !devicePoints.isEmpty()) {
                    // 筛选湿度传感器测点
                    for (MeasurementPoint point : devicePoints) {
                        if (point.getDeviceSubType() == MeasurementPoint.DeviceSubType.HUMIDITY_SENSOR) {
                            humidityPoints.add(point);
                        }
                    }
                }
            }
            
            // 返回湿度测点的JSON，使用ApiResponse格式
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.success("获取湿度数据成功", humidityPoints);
            callback.accept(response.toJson());
        } catch (Exception e) {
            Log.e(TAG, "获取粮情湿度数据失败", e);
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.error("获取湿度数据失败: " + e.getMessage());
            callback.accept(response.toJson());
        }
    }
    
    /**
     * 异步获取特定电缆的数据
     * @param args 参数，包含电缆编号
     * @param requestId 请求ID
     */
    @JavascriptInterface
    public void getCableDataAsync(String args, String requestId) {
        executor.execute(() -> {
            try {
                // 解析参数
                int cableNo = 1; // 默认为1号电缆
                try {
                    // 尝试从参数中提取电缆编号
                    if (args != null && !args.isEmpty()) {
                        com.google.gson.JsonObject jsonArgs = gson.fromJson(args, com.google.gson.JsonObject.class);
                        if (jsonArgs.has("cableNo")) {
                            cableNo = jsonArgs.get("cableNo").getAsInt();
                        }
                    }
                } catch (Exception e) {
                    Log.e(TAG, "解析电缆编号参数失败", e);
                }
                
                // 获取指定电缆的数据
                getCableData(cableNo, result -> handleAsyncResponse(requestId, result));
            } catch (Exception e) {
                Log.e(TAG, "获取电缆数据失败", e);
                ApiResponse<List<MeasurementPoint>> response =
                    ApiResponse.error("获取电缆数据失败: " + e.getMessage());
                handleAsyncResponse(requestId, response.toJson());
            }
        });
    }
    
    // 获取特定电缆的数据
    private void getCableData(int cableNo, Consumer<String> callback) {
        try {
            // 获取粮情检测模块对应的设备-测点映射
            Map<com.warom.sdg.model.DeviceType, List<MeasurementPoint>> grainSituationMap =
                PlcMeasurementConfig.moduleDevicePointsMap.get(ModuleType.GRAIN_SITUATION);
            
            // 如果映射为空，返回空列表
            if (grainSituationMap == null || grainSituationMap.isEmpty()) {
                ApiResponse<List<MeasurementPoint>> response =
                    ApiResponse.success("获取电缆" + cableNo + "数据成功", new ArrayList<>());
                callback.accept(response.toJson());
                return;
            }
            
            // 收集指定电缆的测点到一个列表
            List<MeasurementPoint> cablePoints = new ArrayList<>();
            for (List<MeasurementPoint> devicePoints : grainSituationMap.values()) {
                if (devicePoints != null && !devicePoints.isEmpty()) {
                    // 筛选指定电缆的测点
                    for (MeasurementPoint point : devicePoints) {
                        String englishName = point.getEnglishName();
                        if (englishName != null && englishName.startsWith("Cable" + cableNo + "_")) {
                            cablePoints.add(point);
                        }
                    }
                }
            }
            
            // 返回指定电缆测点的JSON，使用ApiResponse格式
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.success("获取电缆" + cableNo + "数据成功", cablePoints);
            callback.accept(response.toJson());
        } catch (Exception e) {
            Log.e(TAG, "获取电缆" + cableNo + "数据失败", e);
            ApiResponse<List<MeasurementPoint>> response =
                ApiResponse.error("获取电缆" + cableNo + "数据失败: " + e.getMessage());
            callback.accept(response.toJson());
        }
    }

    // --- 内部数据模型 ---

    /**
     * 用于从JS接收历史平均数据请求的参数模型
     */
    private static class HistoricalDataRequest {
        List<Integer> cableNos;
        int durationMinutes;
    }

    /**
     * 用于返回计算出的平均数据的模型
     */
    public static class AverageData {
        private final double averageTemperature;
        private final double averageHumidity;

        public AverageData(double averageTemperature, double averageHumidity) {
            this.averageTemperature = averageTemperature;
            this.averageHumidity = averageHumidity;
        }
    }

    // 实际业务处理 - 获取历史数据的平均值（模拟实现）
    private void getHistoricalAverageData(List<Integer> cableNos, int durationMinutes, Consumer<String> callback) {
        try {
            List<Double> allTemperatures = new ArrayList<>();
            List<Double> allHumidities = new ArrayList<>();
            int dataPoints = 60; // 与mock.js保持一致，生成60个点用于计算

            for (int cableId : cableNos) {
                // 模拟基础温湿度，与mock.js逻辑保持一致
                double baseTemp = 25 + (cableId % 3);
                double baseHumidity = 60 + (cableId % 5);

                for (int i = 0; i < dataPoints; i++) {
                    // 模拟随机波动和时间趋势，与mock.js逻辑保持一致
                    double tempVariation = (Math.random() - 0.5) * 3;
                    double humVariation = (Math.random() - 0.5) * 5;
                    double hourFactor = (double) i / dataPoints;
                    double timeEffect = hourFactor * 2 * Math.sin(hourFactor * Math.PI);

                    double temp = baseTemp + tempVariation + timeEffect;
                    double humidity = baseHumidity + humVariation - timeEffect;

                    allTemperatures.add(temp);
                    
                    // 假设前半部分电缆有湿度数据，与mock.js逻辑保持一致 (总共32条)
                    if (cableId <= 16) {
                        allHumidities.add(humidity);
                    }
                }
            }
            
            // 使用Stream API计算平均值
            double avgTemp = allTemperatures.stream()
                    .mapToDouble(d -> d)
                    .average()
                    .orElse(0.0);

            double avgHum = allHumidities.stream()
                    .mapToDouble(d -> d)
                    .average()
                    .orElse(0.0);
            
            // 创建响应对象
            AverageData averageData = new AverageData(avgTemp, avgHum);

            ApiResponse<AverageData> response = ApiResponse.success("获取历史平均数据成功", averageData);
            callback.accept(response.toJson());

        } catch (Exception e) {
            Log.e(TAG, "计算历史平均数据时出错", e);
            ApiResponse<Object> response = ApiResponse.error("计算历史平均数据时出错: " + e.getMessage());
            callback.accept(response.toJson());
        }
    }
} 